/**
 * 
 */
package com.arx.script.flyweight;

import com.arx.common.GlobalConsts;
import com.arx.interactive.InteractiveObject;

/**
 * @author Donald
 */
public final class ScriptObject {
	/** bit flag storing which events are allowed. */
	private long				allowevents;
	private String				data;
	private LabelInfo[]			labels;
	private long				lastcall;
	/** the array of local {@link ScriptVariable}s. */
	private ScriptVariable[]	lvar		= new ScriptVariable[0];
	private ScriptObject		master;
	private int					numberOfLabels;
	private int					numberOfLocalVars;
	private int[]				shortcut	= new int[GlobalConsts.MAX_SHORTCUT];
	private long				size;
	private long[]				sub			= new long[GlobalConsts.MAX_GOSUB];
	private long[]				timers		= new long[GlobalConsts.MAX_SCRIPTTIMERS];
	/**
	 * Assigns a bit flag for an allowed event.
	 * @param event the event flag
	 */
	public void assignAllowedEvent(final int event) {
		allowevents |= event;
	}
	/** Clears the bit flags for allowed events. */
	public void clearAllowedEvents() {
		allowevents = 0;
	}
	/** Clears all labels assigned to the {@link ScriptObject}. */
	public void clearLabels() {
		numberOfLabels = 0;
		if (labels != null) {
			for (int i = 0; i < labels.length; i++) {
				labels[i] = null;
			}
		}
	}
	/** Clears all local variables assigned to the {@link ScriptObject}. */
	public void clearLocalVariables() {
		numberOfLocalVars = 0;
		if (lvar != null) {
			for (int i = 0; i < lvar.length; i++) {
				if (lvar[i] != null) {
					lvar[i].clear();
				}
				lvar[i] = null;
			}
		}
	}
	/** Clears all local variables assigned to the {@link ScriptObject}. */
	public void clearShortcuts() {
		if (shortcut != null) {
			for (int i = 0; i < shortcut.length; i++) {
				shortcut[i] = -1;
			}
		}
	}
	@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		return super.equals(obj);
	}
	/** Extends the size of the local variables array if needed. */
	public void extendLvarArray() {
		if (lvar.length < numberOfLocalVars) {
			ScriptVariable[] temp = new ScriptVariable[numberOfLocalVars];
			System.arraycopy(lvar, 0, temp, 0, lvar.length);
			lvar = temp;
			temp = null;
		}
	}
	/**
	 * Gets the bit flags for allowed events.
	 * @return long
	 */
	public long getAllowevents() {
		return allowevents;
	}
	/**
	 * Gets the data
	 * @return {@link String}
	 */
	public String getData() {
		return data;
	}
	/**
	 * Gets a local {@link ScriptObject} variable.
	 * @param index the index of the variable
	 * @return {@link LabelInfo}
	 */
	public LabelInfo getLabel(final int index) {
		LabelInfo li = null;
		if (lvar != null && index >= 0 && index < numberOfLabels) {
			li = labels[index];
		}
		return li;
	}
	/**
	 * Gets a local {@link ScriptObject} variable.
	 * @param index the index of the variable
	 * @return {@link ScriptVariable}
	 */
	public ScriptVariable getLocalVariable(final int index) {
		ScriptVariable svar = null;
		if (lvar != null && index >= 0 && index < numberOfLocalVars) {
			svar = lvar[index];
		}
		return svar;
	}
	public ScriptObject getMaster() {
		return master;
	}
	/**
	 * Gets the number of labels.
	 * @return int
	 */
	public int getNumberOfLabels() {
		return numberOfLabels;
	}
	/**
	 * Gets the nblvar.
	 * @return int
	 */
	public int getNumberOfLocalVars() {
		return numberOfLocalVars;
	}
	public int getShortcut(final int index) {
		int val = -1;
		if (index >= 0 && index < GlobalConsts.MAX_SHORTCUT) {
			val = shortcut[index];
		}
		return val;
	}
	public long getSize() {
		return size;
	}
	public long getSub(final int index) {
		long val = -1;
		if (index >= 0 && index < GlobalConsts.MAX_GOSUB) {
			val = sub[index];
		}
		return val;
	}
	public long getTimer(final int index) {
		long val = -1;
		if (index >= 0 && index < GlobalConsts.MAX_SCRIPTTIMERS) {
			val = timers[index];
		}
		return val;
	}
	public long getTimerIndex(final int index) {
		long val = 0;
		if (index >= 0 && index < GlobalConsts.MAX_SCRIPTTIMERS) {
			val = timers[index];
		}
		return val;
	}
	/**
	 * Determines if the {@link InteractiveObject} allows a specific event.
	 * @param event the event flag
	 * @return true if the object has the event set; false otherwise
	 */
	public boolean hasAllowedEvent(final int event) {
		return (allowevents & event) == event;
	}
	public boolean hasData() {
		return data != null && data.length() > 0;
	}
	/**
	 * Determines if a {@link ScriptObject} has labels assigned to it.
	 * @return true if the {@link ScriptObject} has labels; false otherwise
	 */
	public boolean hasLabels() {
		boolean has = false;
		if (labels != null && numberOfLabels > 0) {
			has = true;
		}
		return has;
	}
	/**
	 * Determines if a {@link ScriptObject} has local variables assigned to it.
	 * @return true if the {@link ScriptObject} has local variables; false
	 *         otherwise
	 */
	public boolean hasLocalVariables() {
		return lvar != null && numberOfLocalVars > 0;
	}
	/**
	 * Removed an event from the list of allowed events.
	 * @param event the event flag
	 */
	public void removeAllowedEvent(final int event) {
		allowevents = allowevents & ~event;
	}
	/**
	 * Sets the data
	 * @param val the data to set
	 */
	public void setData(final String val) {
		data = val;
	}
	/**
	 * Sets a local {@link ScriptVariable}.
	 * @param index the index of the variable
	 * @param svar the local {@link ScriptVariable}
	 */
	public void setLocalVariable(final int index, final ScriptVariable svar) {
		// if the index number is valid
		if (index >= 0) {
			// if the local variables array needs to be extended, do so
			if (index >= numberOfLocalVars) {
				numberOfLocalVars = index + 1;
			}
			extendLvarArray();
			// copy the variable into the local variables arrays
			lvar[index] = svar;
		}
	}
	public void setMaster(final ScriptObject val) {
		master = val;
	}
	/**
	 * Sets the number of local variables.
	 * @param val the number to set
	 */
	public void setNumberOfLocalVars(final int val) {
		numberOfLocalVars = val;
		if (lvar.length < numberOfLocalVars) {
			ScriptVariable[] temp = new ScriptVariable[numberOfLocalVars];
			System.arraycopy(lvar, 0, temp, 0, lvar.length);
			lvar = temp;
			temp = null;
		}
	}
	public void setShortcut(final int index, final int val) {
		if (index >= 0 && index < GlobalConsts.MAX_SHORTCUT) {
			shortcut[index] = val;
		}
	}
	public void setSize(final long size) {
		this.size = size;
	}
	public void setSub(final int index, final long val) {
		if (index >= 0 && index < GlobalConsts.MAX_GOSUB) {
			sub[index] = val;
		}
	}
	public void setTimer(final int index, final long val) {
		if (index >= 0 && index < GlobalConsts.MAX_SCRIPTTIMERS) {
			timers[index] = val;
		}
	}
}
